home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr53 / acmalg01.zip / ACM697.FOR < prev    next >
Text File  |  1993-01-01  |  38KB  |  1,074 lines

  1. C      ALGORITHM 697 , COLLECTED ALGORITHMS FROM ACM.
  2. C      THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
  3. C      VOL. 17, NO. 3, SEPTEMBER, 1991, PP. 367.
  4.       PROGRAM  TTUVIP
  5. C
  6. C Test Program for the UVIP3P Subroutine
  7. C
  8. C Hiroshi Akima
  9. C U.S. Department of Commerce, NTIA/ITS
  10. C Version of 89/07/04
  11. C
  12. C This program tests the UVIP3P subroutine by calling UVIP3P, in
  13. C a sequence, with two values of the NP argument, which is the
  14. C degree of the polynomial for the interval between each pair of
  15. C data points.  With each NP value, this program calls UVIP3P in
  16. C three ways:
  17. C (1) in repeated calls with interpolation at a point in
  18. C     each call,
  19. C (2) in one call with interpolation at all points, and
  20. C (3) in one call as in (2) but with inverted data set.
  21. C The program then compares the results with the expected values,
  22. C precalculated and stored in the program, and writes the
  23. C differences in two pages.  If all entries in the last three
  24. C columns on each page are all zeros, UVIP3P is considered to be
  25. C working as expected.  Otherwise, something is wrong in UVIP3P
  26. C and/or the test program itself.
  27. C
  28. C Dummy arguments of the UVIP3P subroutine are described in the
  29. C comments in the subroutine.
  30. C
  31. C Variables and arrays used in this program are
  32. C   NP   = degree of the polynomial for the interval between
  33. C          each pair of data points,
  34. C   NPO  = integer array of dimension 2 containing the two
  35. C          NP values,
  36. C   ND   = number of data points,
  37. C   NI   = number of interpolated points,
  38. C   XD1, YD1
  39. C        = arrays of dimension ND containing the abscissas
  40. C          and ordinates of the data points,
  41. C   XI1  = array of dimension NI containing the abscissas of
  42. C          the desired points,
  43. C   YIE  = doubly-dimensioned array of dimension (NI,2)
  44. C          containing the expected values of the interpolated
  45. C          results for the two NP values in two columns,
  46. C   YI1  = array of dimension NI, where the ordinate values
  47. C          interpolated from the XD1, YD1, and XI1 values in
  48. C          repeated calls are to be stored,
  49. C   YI2  = array of dimension NI, where the ordinate values
  50. C          interpolated from the XD1, YD1, and XI1 values in
  51. C          one call are to be stored,
  52. C   XD3, YD3
  53. C        = arrays of dimension ND, where the abscissas and
  54. C          ordinates of the inverted data points are to be
  55. C          stored,
  56. C   XI3  = array of dimension NI, where the abscissas of the
  57. C          desired points for the inverted data points are to
  58. C          be stored,
  59. C   YI3  = array of dimension NI, where the ordinate values
  60. C          interpolated from the XD3, YD3, and XI3 values in
  61. C          one call are to be stored,
  62. C   DYI1, DYI2, DYI3
  63. C        = arrays of dimension NI, where the differences
  64. C          between the YI1, YI2, and YI3 values and their
  65. C          respective expected values are to be stored.
  66. C
  67. C
  68. C Specification statements
  69.       DIMENSION   NPO(2)
  70.       PARAMETER   (ND=10, NI=31)
  71.       DIMENSION   XD1(ND),YD1(ND),YIE(NI,2),XI1(NI)
  72.       DIMENSION   XD3(ND),YD3(ND),XI3(NI)
  73.       DIMENSION   YI1(NI),YI2(NI),YI3(NI)
  74.       DIMENSION   DYI1(NI),DYI2(NI),DYI3(NI)
  75. C Data statements
  76.       DATA  NPO/ 3, 6/
  77.       DATA  XD1/
  78.      1   1.0, 2.0, 4.0, 6.5, 8.0,10.0,10.5,11.0,13.0,14.0/
  79.       DATA  YD1/
  80.      1   0.0, 0.0, 0.0, 0.0, 0.1, 1.0, 4.5, 8.0,10.0,15.0/
  81.       DATA  XI1/
  82.      1   0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5,
  83.      2   4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5,
  84.      3   8.0, 8.5, 9.0, 9.5,10.0,10.5,11.0,11.5,
  85.      4  12.0,12.5,13.0,13.5,14.0,14.5,15.0/
  86.       DATA  YIE/
  87.      1   8*0.0,
  88.      2   6*0.0, 0.015, 0.052,
  89.      3   0.100, 0.036,-0.045, 0.172, 1.000, 4.500, 8.000,10.075,
  90.      4  10.705,10.483,10.000,11.204,15.000,19.767,24.533,
  91.      1   8*0.0,
  92.      2   6*0.0, 0.020, 0.057,
  93.      3   0.100, 0.134, 0.166, 0.314, 1.000, 4.500, 8.000, 9.689,
  94.      4  10.101,10.180,10.000,11.663,15.000,19.767,24.533/
  95. C Opens the file (for the UNIX operating system).
  96. C  10 OPEN  (6,FILE='TTUOUT',FORM='PRINT')
  97. C Calculation
  98. C Do-loop with respect to the two NP values
  99.    20 DO 79  INP=1,2
  100.         NP=NPO(INP)
  101. C Interpolation in repeated calls at a point in each call
  102.    30   DO 31  II=1,NI
  103.           CALL UVIP3P(NP,ND,XD1,YD1,1,XI1(II),YI1(II))
  104.    31   CONTINUE
  105. C Interpolation in one call at all points
  106.         CALL UVIP3P(NP,ND,XD1,YD1,NI,XI1,YI2)
  107. C Interpolation in one call with inverted data
  108.    40   DO 41  ID=1,ND
  109.           IDI=ND+1-ID
  110.           XD3(IDI)=XD1(1)+XD1(ND)-XD1(ID)
  111.           YD3(IDI)=YD1(ID)
  112.    41   CONTINUE
  113.         DO 42  II=1,NI
  114.           XI3(II)=XD1(1)+XD1(ND)-XI1(II)
  115.    42   CONTINUE
  116.         CALL UVIP3P(NP,ND,XD3,YD3,NI,XI3,YI3)
  117. C Calculation of the differences between the calculated and
  118. C expected values
  119.    50   DO 51  II=1,NI
  120.           DYI1(II)=YI1(II)-YIE(II,INP)
  121.           DYI2(II)=YI2(II)-YIE(II,INP)
  122.           DYI3(II)=YI3(II)-YIE(II,INP)
  123.    51   CONTINUE
  124. C Writing the results
  125.    60   IF (INP.EQ.1)  THEN
  126.           WRITE (*,6060) NP
  127.         ELSE
  128.           WRITE (*,6061) NP
  129.         END IF
  130.         WRITE (*,6062)
  131.         DO 69  II=1,NI
  132.           IF (MOD(II,4).EQ.2)   WRITE (*,6063)
  133.           IF (II.LE.ND)  THEN
  134.             ID=II
  135.             WRITE (*,6064)  XD1(ID),YD1(ID),
  136.      1                      XI1(II),YIE(II,INP),YI1(II),
  137.      2                      DYI1(II),DYI2(II),DYI3(II)
  138.           ELSE
  139.             WRITE (*,6065)  XI1(II),YIE(II,INP),YI1(II),
  140.      1                      DYI1(II),DYI2(II),DYI3(II)
  141.           END IF
  142.    69   CONTINUE
  143.    79 CONTINUE
  144.       STOP
  145. C Format statements
  146.  6060 FORMAT (1H ,
  147.      1  'TTUVIP',14X,'Test Program for UVIP3P',29X,'NP =',I2)
  148.  6061 FORMAT (1H1,
  149.      1  'TTUVIP',14X,'Test Program for UVIP3P',29X,'NP =',I2)
  150.  6062 FORMAT (1X///
  151.      1  6X,'Data Points',9X,'Interpolated Points ',
  152.      2  8X,'      Differences     '//
  153.      3  6X,'XD1      YD1',8X,'XI1      YIE      YI1',
  154.      4  8X,'DYI1     DYI2     DYI3'/)
  155.  6063 FORMAT (1X)
  156.  6064 FORMAT (1X,2F9.3,2X,3F9.3,2X,3F9.3)
  157.  6065 FORMAT (19X,2X,3F9.3,2X,3F9.3)
  158.       END
  159.       SUBROUTINE  UVIP3P(NP,ND,XD,YD,NI,XI, YI)
  160. C
  161. C Univariate Interpolation (Improved Akima Method)
  162. C
  163. C Hiroshi Akima
  164. C U.S. Department of Commerce, NTIA/ITS
  165. C Version of 89/07/04
  166. C
  167. C This subroutine performs univariate interpolation.  It is based
  168. C on the improved A method developed by Hiroshi Akima, 'A method
  169. C of univariate interpolation that has the accuracy of a third-
  170. C degree polynomial,' ACM TOMS, vol. xx, pp. xxx-xxx, 19xx.  (The
  171. C equation numbers referred to in the comments below are those in
  172. C the paper.)
  173. C
  174. C In this method, the interpolating function is a piecewise
  175. C function composed of a set of polynomials applicable to
  176. C successive intervals of the given data points.  This method
  177. C uses third-degree polynomials as the default, but the user has
  178. C an option to use higher-degree polynomial to reduce undulations
  179. C in resulting curves.
  180. C
  181. C This method has the accuracy of a third-degree polynomial if
  182. C the degree of the polynomials for the interpolating function is
  183. C set to three.
  184. C
  185. C The input arguments are
  186. C   NP = degree of the polynomials for the interpolating
  187. C        function,
  188. C   ND = number of input data points
  189. C        (must be equal to 2 or greater),
  190. C   XD = array of dimension ND, containing the abscissas of
  191. C        the input data points
  192. C        (must be in a monotonic increasing order),
  193. C   YD = array of dimension ND, containing the ordinates of
  194. C        the input data points,
  195. C   NI = number of points for which interpolation is desired
  196. C        (must be equal to 1 or greater),
  197. C   XI = array of dimension NI, containing the abscissas of
  198. C        the desired points.
  199. C
  200. C The output argument is
  201. C   YI = array of dimension NI, where the ordinates of the
  202. C        desired points are to be stored.
  203. C
  204. C If an integer value smaller than 3 is given to the NP argument,
  205. C this subroutine assumes NP = 3.
  206. C
  207. C The XI array elements need not be monotonic, but this
  208. C subroutine interpolates faster if the XI array elements are
  209. C given in a monotonic order.
  210. C
  211. C If the XI array element is less than XD(1) or greater than
  212. C XD(ND), this subroutine linearly interpolates the YI value.
  213. C
  214. C
  215. C Specification statement
  216.       DIMENSION   XD(*),YD(*),XI(*), YI(*)
  217. C Error check
  218.    10 IF (ND.LE.1)   GO TO 90
  219.       IF (NI.LE.0)   GO TO 91
  220.       DO 11  ID=2,ND
  221.         IF (XD(ID).LE.XD(ID-1))     GO TO 92
  222.    11 CONTINUE
  223. C Branches off special cases.
  224.       IF (ND.LE.4)   GO TO 50
  225. C General case  --  Five data points of more
  226. C Calculates some local variables.
  227.    20 NP0=MAX(3,NP)
  228.       NPM1=NP0-1
  229.       RENPM1=NPM1
  230.       RENNM2=NP0*(NP0-2)
  231. C Main calculation for the general case
  232. C First (outermost) DO-loop with respect to the desired points
  233.    30 DO 39  II=1,NI
  234.         IF (II.EQ.1)      IINTPV=-1
  235.         XII=XI(II)
  236. C Locates the interval that includes the desired point by binary
  237. C search.
  238.         IF (XII.LE.XD(1))  THEN
  239.           IINT=0
  240.         ELSE IF (XII.LT.XD(ND))  THEN
  241.           IDMN=1
  242.           IDMX=ND
  243.           IDMD=(IDMN+IDMX)/2
  244.    31     IF (XII.GE.XD(IDMD))  THEN
  245.             IDMN=IDMD
  246.           ELSE
  247.             IDMX=IDMD
  248.           END IF
  249.           IDMD=(IDMN+IDMX)/2
  250.           IF (IDMD.GT.IDMN)    GO TO 31
  251.           IINT=IDMD
  252.         ELSE
  253.           IINT=ND
  254.         END IF
  255. C End of locating the interval of interest
  256. C Interpolation or extrapolation in one of the three subcases
  257.         IF (IINT.LE.0)  THEN
  258. C Subcase 1  --  Linear extrapolation when the abscissa of the
  259. C                desired point is equal to that of the first data
  260. C                point or less.
  261. C Estimates the first derivative when the interval is not the
  262. C same as the one for the previous desired point.  --
  263. C cf. Equation (8)
  264.           IF (IINT.NE.IINTPV)  THEN
  265.             IINTPV=IINT
  266.             X0=XD(1)
  267.             X1=XD(2)-X0
  268.             X2=XD(3)-X0
  269.             X3=XD(4)-X0
  270.             Y0=YD(1)
  271.             Y1=YD(2)-Y0
  272.             Y2=YD(3)-Y0
  273.             Y3=YD(4)-Y0
  274.             DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  275.             A1=(((X2*X3)**2)*(X3-X2)*Y1
  276.      1         +((X3*X1)**2)*(X1-X3)*Y2
  277.      2         +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  278.           END IF
  279. C Evaluates the YI value.
  280.           YI(II)=Y0+A1*(XII-X0)
  281. C End of Subcase 1
  282.         ELSE IF (IINT.GE.ND)  THEN
  283. C Subcase 2  --  Linear extrapolation when the abscissa of the
  284. C                desired point is equal to that of the last data
  285. C                point or greater.
  286. C Estimates the first derivative when the interval is not the
  287. C same as the one for the previous desired point.  --
  288. C cf. Equation (8)
  289.           IF (IINT.NE.IINTPV)  THEN
  290.             IINTPV=IINT
  291.             X0=XD(ND)
  292.             X1=XD(ND-1)-X0
  293.             X2=XD(ND-2)-X0
  294.             X3=XD(ND-3)-X0
  295.             Y0=YD(ND)
  296.             Y1=YD(ND-1)-Y0
  297.             Y2=YD(ND-2)-Y0
  298.             Y3=YD(ND-3)-Y0
  299.             DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  300.             A1=(((X2*X3)**2)*(X3-X2)*Y1
  301.      1         +((X3*X1)**2)*(X1-X3)*Y2
  302.      2         +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  303.           END IF
  304. C Evaluates the YI value.
  305.           YI(II)=Y0+A1*(XII-X0)
  306. C End of Subcase 2
  307.         ELSE
  308. C Subcase 3  --  Interpolation when the abscissa of the desired
  309. C                point is  between those of the first and last
  310. C                data points.
  311. C Calculates the coefficients of the third-degree polynomial (for
  312. C NP.LE.3) or the factors for the higher-degree polynomials (for
  313. C NP.GT.3), when the interval is not the same as the one for the
  314. C previous desired point.
  315.           IF (IINT.NE.IINTPV)  THEN
  316.             IINTPV=IINT
  317. C The second DO-loop with respect to the two endpoints of the
  318. C interval
  319.             DO 37  IEPT=1,2
  320. C Calculates the estimate of the first derivative at an endpoint.
  321. C Initial setting for calculation
  322.               ID0=IINT+IEPT-1
  323.               X0=XD(ID0)
  324.               Y0=YD(ID0)
  325.               SMPEF=0.0
  326.               SMWTF=0.0
  327.               SMPEI=0.0
  328.               SMWTI=0.0
  329. C The third (innermost) DO-loop with respect to the four primary
  330. C estimate of the first derivative
  331.               DO 36  IPE=1,4
  332. C Selects point numbers of four consecutive data points for
  333. C calculating the primary estimate of the first derivative.
  334.                 IF (IPE.EQ.1)  THEN
  335.                   ID1=ID0-3
  336.                   ID2=ID0-2
  337.                   ID3=ID0-1
  338.                 ELSE IF (IPE.EQ.2)  THEN
  339.                   ID1=ID0+1
  340.                 ELSE IF (IPE.EQ.3)  THEN
  341.                   ID2=ID0+2
  342.                 ELSE
  343.                   ID3=ID0+3
  344.                 END IF
  345. C Checks if any point number falls outside the legitimate range
  346. C (between 1 and ND).  Skips calculation of the primary estimate
  347. C if any does.
  348.                 IF (ID1.LT.1.OR.ID2.LT.1.OR.ID3.LT.1.OR.
  349.      1              ID1.GT.ND.OR.ID2.GT.ND.OR.ID3.GT.ND)
  350.      2               GO TO 36
  351. C Calculates the primary estimate of the first derivative  --
  352. C cf. Equation (8)
  353.                 X1=XD(ID1)-X0
  354.                 X2=XD(ID2)-X0
  355.                 X3=XD(ID3)-X0
  356.                 Y1=YD(ID1)-Y0
  357.                 Y2=YD(ID2)-Y0
  358.                 Y3=YD(ID3)-Y0
  359.                 DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  360.                 PE=(((X2*X3)**2)*(X3-X2)*Y1
  361.      1             +((X3*X1)**2)*(X1-X3)*Y2
  362.      2             +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  363. C Calculates the volatility factor, VOL, and distance factor,
  364. C SXX, for the primary estimate.  --  cf. Equations (9) and (11)
  365.                 SX=X1+X2+X3
  366.                 SY=Y1+Y2+Y3
  367.                 SXX=X1*X1+X2*X2+X3*X3
  368.                 SXY=X1*Y1+X2*Y2+X3*Y3
  369.                 DNM=4.0*SXX-SX*SX
  370.                 B0=(SXX*SY-SX*SXY)/DNM
  371.                 B1=(4.0*SXY-SX*SY)/DNM
  372.                 DY0=-B0
  373.                 DY1=Y1-(B0+B1*X1)
  374.                 DY2=Y2-(B0+B1*X2)
  375.                 DY3=Y3-(B0+B1*X3)
  376.                 VOL=DY0*DY0+DY1*DY1+DY2*DY2+DY3*DY3
  377. C Calculates the EPSLN value, which is used to decide whether or
  378. C not the volatility factor, VOL, is essentially zero.
  379.                 EPSLN=(YD(ID0)**2+YD(ID1)**2
  380.      1                +YD(ID2)**2+YD(ID3)**2)*1.0E-12
  381. C Accumulates the weighted primary estimates.  --
  382. C cf. Equations (13) and (14)
  383.                 IF (VOL.GT.EPSLN)  THEN
  384. C - For finite weight.
  385.                   WT=1.0/(VOL*SXX)
  386.                   SMPEF=SMPEF+PE*WT
  387.                   SMWTF=SMWTF+WT
  388.                 ELSE
  389. C - For infinite weight.
  390.                   SMPEI=SMPEI+PE
  391.                   SMWTI=SMWTI+1.0
  392.                 END IF
  393.    36         CONTINUE
  394. C End of the third DO-loop
  395. C Calculates the final estimate of the first derivative.  --
  396. C cf. Equation (14)
  397.               IF (SMWTI.LT.0.5)  THEN
  398. C - When no infinite weights exist.
  399.                 YP=SMPEF/SMWTF
  400.               ELSE
  401. C - When infinite weights exist.
  402.                 YP=SMPEI/SMWTI
  403.               END IF
  404.               IF (IEPT.EQ.1)  THEN
  405.                 YP0=YP
  406.               ELSE
  407.                 YP1=YP
  408.               END IF
  409. C End of the calculation of the estimate of the first derivative
  410. C at an endpoint
  411.    37       CONTINUE
  412. C End of the second DO-loop
  413.             IF (NP0.LE.3)  THEN
  414. C Calculates the coefficients of the third-degree polynomial
  415. C (when NP.LE.3).  --  cf. Equation (4)
  416.               DX=XD(IINT+1)-XD(IINT)
  417.               DY=YD(IINT+1)-YD(IINT)
  418.               A0=YD(IINT)
  419.               A1=YP0
  420.               YP1=YP1-YP0
  421.               YP0=YP0-DY/DX
  422.               A2=-(3.0*YP0+YP1)/DX
  423.               A3= (2.0*YP0+YP1)/(DX*DX)
  424.             ELSE
  425. C Calculates the factors for the higher-degree polynomials
  426. C (when NP.GT.3).  --  cf. Equation (20)
  427.               DX=XD(IINT+1)-XD(IINT)
  428.               DY=YD(IINT+1)-YD(IINT)
  429.               T0=YP0*DX-DY
  430.               T1=YP1*DX-DY
  431.               AA0= (T0+RENPM1*T1)/RENNM2
  432.               AA1=-(RENPM1*T0+T1)/RENNM2
  433.             END IF
  434.           END IF
  435. C End of the calculation of the coefficients of the third-degree
  436. C polynomial (when NP.LE.3) or the factors for the higher-degree
  437. C polynomials (when NP.GT.3), when the interval is not the same
  438. C as the one for the previous desired point.
  439. C Evaluates the YI value.
  440.           IF (NP0.LE.3)  THEN
  441. C - With a third-degree polynomial.  --  cf. Equation (3)
  442.             XX=XII-XD(IINT)
  443.             YI(II)=A0+XX*(A1+XX*(A2+XX*A3))
  444.           ELSE
  445. C - With a higher-degree polynomial.  --  cf. Equation (19)
  446.             U=(XII-XD(IINT))/DX
  447.             UC=1.0-U
  448.             V=AA0*((U**NP0)-U)+AA1*((UC**NP0)-UC)
  449.             YI(II)=YD(IINT)+DY*U+V
  450.           END IF
  451. C End of Subcase 3
  452.         END IF
  453.    39 CONTINUE
  454. C End of the first DO-loop
  455. C End of general case
  456.       RETURN
  457. C Special cases  --  Four data points or less
  458. C Preliminary processing for the special cases
  459.    50 X0=XD(1)
  460.       Y0=YD(1)
  461.       X1=XD(2)-X0
  462.       Y1=YD(2)-Y0
  463.       IF (ND.EQ.2)   GO TO 60
  464.       X2=XD(3)-X0
  465.       Y2=YD(3)-Y0
  466.       IF (ND.EQ.3)   GO TO 70
  467.       X3=XD(4)-X0
  468.       Y3=YD(4)-Y0
  469.       GO TO 80
  470. C Special Case 1  --  Two data points
  471. C (Linear interpolation and extrapolation)
  472.    60 A1=Y1/X1
  473.       DO 61  II=1,NI
  474.         YI(II)=Y0+A1*(XI(II)-X0)
  475.    61 CONTINUE
  476. C End of Special Case 1
  477.       RETURN
  478. C Special Case 2  --  Three data points
  479. C (Quadratic interpolation and linear extrapolation)
  480.    70 DLT=X1*X2*(X2-X1)
  481.       A1=(X2*X2*Y1-X1*X1*Y2)/DLT
  482.       A2=(X1*Y2-X2*Y1)/DLT
  483.       A12=2.0*A2*X2+A1
  484.       DO 71  II=1,NI
  485.         XX=XI(II)-X0
  486.         IF (XX.LE.0.0)  THEN
  487.           YI(II)=Y0+A1*XX
  488.         ELSE IF (XX.LT.X2) THEN
  489.           YI(II)=Y0+XX*(A1+XX*A2)
  490.         ELSE
  491.           YI(II)=Y0+Y2+A12*(XX-X2)
  492.         END IF
  493.    71 CONTINUE
  494. C End of Special Case 2
  495.       RETURN
  496. C Special Case 3  --  Four data points
  497. C (Cubic interpolation and linear extrapolation)
  498.    80 DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  499.       A1=(((X2*X3)**2)*(X3-X2)*Y1
  500.      1   +((X3*X1)**2)*(X1-X3)*Y2
  501.      2   +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  502.       A2=(X2*X3*(X2*X2-X3*X3)*Y1
  503.      1   +X3*X1*(X3*X3-X1*X1)*Y2
  504.      2   +X1*X2*(X1*X1-X2*X2)*Y3)/DLT
  505.       A3=(X2*X3*(X3-X2)*Y1
  506.      1   +X3*X1*(X1-X3)*Y2
  507.      2   +X1*X2*(X2-X1)*Y3)/DLT
  508.       A13=(3.0*A3*X3+2.0*A2)*X3+A1
  509.       DO 81  II=1,NI
  510.         XX=XI(II)-X0
  511.         IF (XX.LE.0.0)  THEN
  512.           YI(II)=Y0+A1*XX
  513.         ELSE IF (XX.LT.X3) THEN
  514.           YI(II)=Y0+XX*(A1+XX*(A2+XX*A3))
  515.         ELSE
  516.           YI(II)=Y0+Y3+A13*(XX-X3)
  517.         END IF
  518.    81 CONTINUE
  519. C End of Special Case 3
  520.       RETURN
  521. C Error exit
  522.    90 WRITE (*,99090) ND
  523.       GO TO 99
  524.    91 WRITE (*,99091) NI
  525.       GO TO 99
  526.    92 WRITE (*,99092) ID,XD(ID-1),XD(ID)
  527.    99 WRITE (*,99099)
  528.       RETURN
  529. C Format statements for error messages
  530. 99090 FORMAT (1X/ ' ***   Insufficient data points.'
  531.      1  7X,'ND =',I3)
  532. 99091 FORMAT (1X/ ' ***   No desired points.'
  533.      1  7X,'NI =',I3)
  534. 99092 FORMAT (1X/ ' ***   Two data points identical or out of ',
  535.      1  'sequence.'/
  536.      2  7X,'ID, XD(ID-1), XD(ID) =',I5,2F10.3)
  537. 99099 FORMAT (' Error detected in the UVIP3P subroutine'/)
  538.       END
  539.       PROGRAM  TTUVIP
  540. C
  541. C Test Program for the UVIP3P Subroutine
  542. C
  543. C Hiroshi Akima
  544. C U.S. Department of Commerce, NTIA/ITS
  545. C Version of 89/07/04
  546. C
  547. C This program tests the UVIP3P subroutine by calling UVIP3P, in
  548. C a sequence, with two values of the NP argument, which is the
  549. C degree of the polynomial for the interval between each pair of
  550. C data points.  With each NP value, this program calls UVIP3P in
  551. C three ways:
  552. C (1) in repeated calls with interpolation at a point in
  553. C     each call,
  554. C (2) in one call with interpolation at all points, and
  555. C (3) in one call as in (2) but with inverted data set.
  556. C The program then compares the results with the expected values,
  557. C precalculated and stored in the program, and writes the
  558. C differences in two pages.  If all entries in the last three
  559. C columns on each page are all zeros, UVIP3P is considered to be
  560. C working as expected.  Otherwise, something is wrong in UVIP3P
  561. C and/or the test program itself.
  562. C
  563. C Dummy arguments of the UVIP3P subroutine are described in the
  564. C comments in the subroutine.
  565. C
  566. C Variables and arrays used in this program are
  567. C   NP   = degree of the polynomial for the interval between
  568. C          each pair of data points,
  569. C   NPO  = integer array of dimension 2 containing the two
  570. C          NP values,
  571. C   ND   = number of data points,
  572. C   NI   = number of interpolated points,
  573. C   XD1, YD1
  574. C        = arrays of dimension ND containing the abscissas
  575. C          and ordinates of the data points,
  576. C   XI1  = array of dimension NI containing the abscissas of
  577. C          the desired points,
  578. C   YIE  = doubly-dimensioned array of dimension (NI,2)
  579. C          containing the expected values of the interpolated
  580. C          results for the two NP values in two columns,
  581. C   YI1  = array of dimension NI, where the ordinate values
  582. C          interpolated from the XD1, YD1, and XI1 values in
  583. C          repeated calls are to be stored,
  584. C   YI2  = array of dimension NI, where the ordinate values
  585. C          interpolated from the XD1, YD1, and XI1 values in
  586. C          one call are to be stored,
  587. C   XD3, YD3
  588. C        = arrays of dimension ND, where the abscissas and
  589. C          ordinates of the inverted data points are to be
  590. C          stored,
  591. C   XI3  = array of dimension NI, where the abscissas of the
  592. C          desired points for the inverted data points are to
  593. C          be stored,
  594. C   YI3  = array of dimension NI, where the ordinate values
  595. C          interpolated from the XD3, YD3, and XI3 values in
  596. C          one call are to be stored,
  597. C   DYI1, DYI2, DYI3
  598. C        = arrays of dimension NI, where the differences
  599. C          between the YI1, YI2, and YI3 values and their
  600. C          respective expected values are to be stored.
  601. C
  602. C
  603. C Specification statements
  604.       DIMENSION   NPO(2)
  605.       PARAMETER   (ND=10, NI=31)
  606.       DIMENSION   XD1(ND),YD1(ND),YIE(NI,2),XI1(NI)
  607.       DIMENSION   XD3(ND),YD3(ND),XI3(NI)
  608.       DIMENSION   YI1(NI),YI2(NI),YI3(NI)
  609.       DIMENSION   DYI1(NI),DYI2(NI),DYI3(NI)
  610. C Data statements
  611.       DATA  NPO/ 3, 6/
  612.       DATA  XD1/
  613.      1   1.0, 2.0, 4.0, 6.5, 8.0,10.0,10.5,11.0,13.0,14.0/
  614.       DATA  YD1/
  615.      1   0.0, 0.0, 0.0, 0.0, 0.1, 1.0, 4.5, 8.0,10.0,15.0/
  616.       DATA  XI1/
  617.      1   0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5,
  618.      2   4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5,
  619.      3   8.0, 8.5, 9.0, 9.5,10.0,10.5,11.0,11.5,
  620.      4  12.0,12.5,13.0,13.5,14.0,14.5,15.0/
  621.       DATA  YIE/
  622.      1   8*0.0,
  623.      2   6*0.0, 0.015, 0.052,
  624.      3   0.100, 0.036,-0.045, 0.172, 1.000, 4.500, 8.000,10.075,
  625.      4  10.705,10.483,10.000,11.204,15.000,19.767,24.533,
  626.      1   8*0.0,
  627.      2   6*0.0, 0.020, 0.057,
  628.      3   0.100, 0.134, 0.166, 0.314, 1.000, 4.500, 8.000, 9.689,
  629.      4  10.101,10.180,10.000,11.663,15.000,19.767,24.533/
  630. C Opens the file (for the UNIX operating system).
  631.    10 OPEN  (6,FILE='TTUOUT',FORM='PRINT')
  632. C Calculation
  633. C Do-loop with respect to the two NP values
  634.    20 DO 79  INP=1,2
  635.         NP=NPO(INP)
  636. C Interpolation in repeated calls at a point in each call
  637.    30   DO 31  II=1,NI
  638.           CALL UVIP3P(NP,ND,XD1,YD1,1,XI1(II),YI1(II))
  639.    31   CONTINUE
  640. C Interpolation in one call at all points
  641.         CALL UVIP3P(NP,ND,XD1,YD1,NI,XI1,YI2)
  642. C Interpolation in one call with inverted data
  643.    40   DO 41  ID=1,ND
  644.           IDI=ND+1-ID
  645.           XD3(IDI)=XD1(1)+XD1(ND)-XD1(ID)
  646.           YD3(IDI)=YD1(ID)
  647.    41   CONTINUE
  648.         DO 42  II=1,NI
  649.           XI3(II)=XD1(1)+XD1(ND)-XI1(II)
  650.    42   CONTINUE
  651.         CALL UVIP3P(NP,ND,XD3,YD3,NI,XI3,YI3)
  652. C Calculation of the differences between the calculated and
  653. C expected values
  654.    50   DO 51  II=1,NI
  655.           DYI1(II)=YI1(II)-YIE(II,INP)
  656.           DYI2(II)=YI2(II)-YIE(II,INP)
  657.           DYI3(II)=YI3(II)-YIE(II,INP)
  658.    51   CONTINUE
  659. C Writing the results
  660.    60   IF (INP.EQ.1)  THEN
  661.           WRITE (*,6060) NP
  662.         ELSE
  663.           WRITE (*,6061) NP
  664.         END IF
  665.         WRITE (*,6062)
  666.         DO 69  II=1,NI
  667.           IF (MOD(II,4).EQ.2)   WRITE (*,6063)
  668.           IF (II.LE.ND)  THEN
  669.             ID=II
  670.             WRITE (*,6064)  XD1(ID),YD1(ID),
  671.      1                      XI1(II),YIE(II,INP),YI1(II),
  672.      2                      DYI1(II),DYI2(II),DYI3(II)
  673.           ELSE
  674.             WRITE (*,6065)  XI1(II),YIE(II,INP),YI1(II),
  675.      1                      DYI1(II),DYI2(II),DYI3(II)
  676.           END IF
  677.    69   CONTINUE
  678.    79 CONTINUE
  679.       STOP
  680. C Format statements
  681.  6060 FORMAT (1H ,
  682.      1  'TTUVIP',14X,'Test Program for UVIP3P',29X,'NP =',I2)
  683.  6061 FORMAT (1H1,
  684.      1  'TTUVIP',14X,'Test Program for UVIP3P',29X,'NP =',I2)
  685.  6062 FORMAT (1X///
  686.      1  6X,'Data Points',9X,'Interpolated Points ',
  687.      2  8X,'      Differences     '//
  688.      3  6X,'XD1      YD1',8X,'XI1      YIE      YI1',
  689.      4  8X,'DYI1     DYI2     DYI3'/)
  690.  6063 FORMAT (1X)
  691.  6064 FORMAT (1X,2F9.3,2X,3F9.3,2X,3F9.3)
  692.  6065 FORMAT (19X,2X,3F9.3,2X,3F9.3)
  693.       END
  694.       SUBROUTINE  UVIP3P(NP,ND,XD,YD,NI,XI, YI)
  695. C
  696. C Univariate Interpolation (Improved Akima Method)
  697. C
  698. C Hiroshi Akima
  699. C U.S. Department of Commerce, NTIA/ITS
  700. C Version of 89/07/04
  701. C
  702. C This subroutine performs univariate interpolation.  It is based
  703. C on the improved A method developed by Hiroshi Akima, 'A method
  704. C of univariate interpolation that has the accuracy of a third-
  705. C degree polynomial,' ACM TOMS, vol. xx, pp. xxx-xxx, 19xx.  (The
  706. C equation numbers referred to in the comments below are those in
  707. C the paper.)
  708. C
  709. C In this method, the interpolating function is a piecewise
  710. C function composed of a set of polynomials applicable to
  711. C successive intervals of the given data points.  This method
  712. C uses third-degree polynomials as the default, but the user has
  713. C an option to use higher-degree polynomial to reduce undulations
  714. C in resulting curves.
  715. C
  716. C This method has the accuracy of a third-degree polynomial if
  717. C the degree of the polynomials for the interpolating function is
  718. C set to three.
  719. C
  720. C The input arguments are
  721. C   NP = degree of the polynomials for the interpolating
  722. C        function,
  723. C   ND = number of input data points
  724. C        (must be equal to 2 or greater),
  725. C   XD = array of dimension ND, containing the abscissas of
  726. C        the input data points
  727. C        (must be in a monotonic increasing order),
  728. C   YD = array of dimension ND, containing the ordinates of
  729. C        the input data points,
  730. C   NI = number of points for which interpolation is desired
  731. C        (must be equal to 1 or greater),
  732. C   XI = array of dimension NI, containing the abscissas of
  733. C        the desired points.
  734. C
  735. C The output argument is
  736. C   YI = array of dimension NI, where the ordinates of the
  737. C        desired points are to be stored.
  738. C
  739. C If an integer value smaller than 3 is given to the NP argument,
  740. C this subroutine assumes NP = 3.
  741. C
  742. C The XI array elements need not be monotonic, but this
  743. C subroutine interpolates faster if the XI array elements are
  744. C given in a monotonic order.
  745. C
  746. C If the XI array element is less than XD(1) or greater than
  747. C XD(ND), this subroutine linearly interpolates the YI value.
  748. C
  749. C
  750. C Specification statement
  751.       DIMENSION   XD(*),YD(*),XI(*), YI(*)
  752. C Error check
  753.    10 IF (ND.LE.1)   GO TO 90
  754.       IF (NI.LE.0)   GO TO 91
  755.       DO 11  ID=2,ND
  756.         IF (XD(ID).LE.XD(ID-1))     GO TO 92
  757.    11 CONTINUE
  758. C Branches off special cases.
  759.       IF (ND.LE.4)   GO TO 50
  760. C General case  --  Five data points of more
  761. C Calculates some local variables.
  762.    20 NP0=MAX(3,NP)
  763.       NPM1=NP0-1
  764.       RENPM1=NPM1
  765.       RENNM2=NP0*(NP0-2)
  766. C Main calculation for the general case
  767. C First (outermost) DO-loop with respect to the desired points
  768.    30 DO 39  II=1,NI
  769.         IF (II.EQ.1)      IINTPV=-1
  770.         XII=XI(II)
  771. C Locates the interval that includes the desired point by binary
  772. C search.
  773.         IF (XII.LE.XD(1))  THEN
  774.           IINT=0
  775.         ELSE IF (XII.LT.XD(ND))  THEN
  776.           IDMN=1
  777.           IDMX=ND
  778.           IDMD=(IDMN+IDMX)/2
  779.    31     IF (XII.GE.XD(IDMD))  THEN
  780.             IDMN=IDMD
  781.           ELSE
  782.             IDMX=IDMD
  783.           END IF
  784.           IDMD=(IDMN+IDMX)/2
  785.           IF (IDMD.GT.IDMN)    GO TO 31
  786.           IINT=IDMD
  787.         ELSE
  788.           IINT=ND
  789.         END IF
  790. C End of locating the interval of interest
  791. C Interpolation or extrapolation in one of the three subcases
  792.         IF (IINT.LE.0)  THEN
  793. C Subcase 1  --  Linear extrapolation when the abscissa of the
  794. C                desired point is equal to that of the first data
  795. C                point or less.
  796. C Estimates the first derivative when the interval is not the
  797. C same as the one for the previous desired point.  --
  798. C cf. Equation (8)
  799.           IF (IINT.NE.IINTPV)  THEN
  800.             IINTPV=IINT
  801.             X0=XD(1)
  802.             X1=XD(2)-X0
  803.             X2=XD(3)-X0
  804.             X3=XD(4)-X0
  805.             Y0=YD(1)
  806.             Y1=YD(2)-Y0
  807.             Y2=YD(3)-Y0
  808.             Y3=YD(4)-Y0
  809.             DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  810.             A1=(((X2*X3)**2)*(X3-X2)*Y1
  811.      1         +((X3*X1)**2)*(X1-X3)*Y2
  812.      2         +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  813.           END IF
  814. C Evaluates the YI value.
  815.           YI(II)=Y0+A1*(XII-X0)
  816. C End of Subcase 1
  817.         ELSE IF (IINT.GE.ND)  THEN
  818. C Subcase 2  --  Linear extrapolation when the abscissa of the
  819. C                desired point is equal to that of the last data
  820. C                point or greater.
  821. C Estimates the first derivative when the interval is not the
  822. C same as the one for the previous desired point.  --
  823. C cf. Equation (8)
  824.           IF (IINT.NE.IINTPV)  THEN
  825.             IINTPV=IINT
  826.             X0=XD(ND)
  827.             X1=XD(ND-1)-X0
  828.             X2=XD(ND-2)-X0
  829.             X3=XD(ND-3)-X0
  830.             Y0=YD(ND)
  831.             Y1=YD(ND-1)-Y0
  832.             Y2=YD(ND-2)-Y0
  833.             Y3=YD(ND-3)-Y0
  834.             DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  835.             A1=(((X2*X3)**2)*(X3-X2)*Y1
  836.      1         +((X3*X1)**2)*(X1-X3)*Y2
  837.      2         +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  838.           END IF
  839. C Evaluates the YI value.
  840.           YI(II)=Y0+A1*(XII-X0)
  841. C End of Subcase 2
  842.         ELSE
  843. C Subcase 3  --  Interpolation when the abscissa of the desired
  844. C                point is  between those of the first and last
  845. C                data points.
  846. C Calculates the coefficients of the third-degree polynomial (for
  847. C NP.LE.3) or the factors for the higher-degree polynomials (for
  848. C NP.GT.3), when the interval is not the same as the one for the
  849. C previous desired point.
  850.           IF (IINT.NE.IINTPV)  THEN
  851.             IINTPV=IINT
  852. C The second DO-loop with respect to the two endpoints of the
  853. C interval
  854.             DO 37  IEPT=1,2
  855. C Calculates the estimate of the first derivative at an endpoint.
  856. C Initial setting for calculation
  857.               ID0=IINT+IEPT-1
  858.               X0=XD(ID0)
  859.               Y0=YD(ID0)
  860.               SMPEF=0.0
  861.               SMWTF=0.0
  862.               SMPEI=0.0
  863.               SMWTI=0.0
  864. C The third (innermost) DO-loop with respect to the four primary
  865. C estimate of the first derivative
  866.               DO 36  IPE=1,4
  867. C Selects point numbers of four consecutive data points for
  868. C calculating the primary estimate of the first derivative.
  869.                 IF (IPE.EQ.1)  THEN
  870.                   ID1=ID0-3
  871.                   ID2=ID0-2
  872.                   ID3=ID0-1
  873.                 ELSE IF (IPE.EQ.2)  THEN
  874.                   ID1=ID0+1
  875.                 ELSE IF (IPE.EQ.3)  THEN
  876.                   ID2=ID0+2
  877.                 ELSE
  878.                   ID3=ID0+3
  879.                 END IF
  880. C Checks if any point number falls outside the legitimate range
  881. C (between 1 and ND).  Skips calculation of the primary estimate
  882. C if any does.
  883.                 IF (ID1.LT.1.OR.ID2.LT.1.OR.ID3.LT.1.OR.
  884.      1              ID1.GT.ND.OR.ID2.GT.ND.OR.ID3.GT.ND)
  885.      2               GO TO 36
  886. C Calculates the primary estimate of the first derivative  --
  887. C cf. Equation (8)
  888.                 X1=XD(ID1)-X0
  889.                 X2=XD(ID2)-X0
  890.                 X3=XD(ID3)-X0
  891.                 Y1=YD(ID1)-Y0
  892.                 Y2=YD(ID2)-Y0
  893.                 Y3=YD(ID3)-Y0
  894.                 DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  895.                 PE=(((X2*X3)**2)*(X3-X2)*Y1
  896.      1             +((X3*X1)**2)*(X1-X3)*Y2
  897.      2             +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  898. C Calculates the volatility factor, VOL, and distance factor,
  899. C SXX, for the primary estimate.  --  cf. Equations (9) and (11)
  900.                 SX=X1+X2+X3
  901.                 SY=Y1+Y2+Y3
  902.                 SXX=X1*X1+X2*X2+X3*X3
  903.                 SXY=X1*Y1+X2*Y2+X3*Y3
  904.                 DNM=4.0*SXX-SX*SX
  905.                 B0=(SXX*SY-SX*SXY)/DNM
  906.                 B1=(4.0*SXY-SX*SY)/DNM
  907.                 DY0=-B0
  908.                 DY1=Y1-(B0+B1*X1)
  909.                 DY2=Y2-(B0+B1*X2)
  910.                 DY3=Y3-(B0+B1*X3)
  911.                 VOL=DY0*DY0+DY1*DY1+DY2*DY2+DY3*DY3
  912. C Calculates the EPSLN value, which is used to decide whether or
  913. C not the volatility factor, VOL, is essentially zero.
  914.                 EPSLN=(YD(ID0)**2+YD(ID1)**2
  915.      1                +YD(ID2)**2+YD(ID3)**2)*1.0E-12
  916. C Accumulates the weighted primary estimates.  --
  917. C cf. Equations (13) and (14)
  918.                 IF (VOL.GT.EPSLN)  THEN
  919. C - For finite weight.
  920.                   WT=1.0/(VOL*SXX)
  921.                   SMPEF=SMPEF+PE*WT
  922.                   SMWTF=SMWTF+WT
  923.                 ELSE
  924. C - For infinite weight.
  925.                   SMPEI=SMPEI+PE
  926.                   SMWTI=SMWTI+1.0
  927.                 END IF
  928.    36         CONTINUE
  929. C End of the third DO-loop
  930. C Calculates the final estimate of the first derivative.  --
  931. C cf. Equation (14)
  932.               IF (SMWTI.LT.0.5)  THEN
  933. C - When no infinite weights exist.
  934.                 YP=SMPEF/SMWTF
  935.               ELSE
  936. C - When infinite weights exist.
  937.                 YP=SMPEI/SMWTI
  938.               END IF
  939.               IF (IEPT.EQ.1)  THEN
  940.                 YP0=YP
  941.               ELSE
  942.                 YP1=YP
  943.               END IF
  944. C End of the calculation of the estimate of the first derivative
  945. C at an endpoint
  946.    37       CONTINUE
  947. C End of the second DO-loop
  948.             IF (NP0.LE.3)  THEN
  949. C Calculates the coefficients of the third-degree polynomial
  950. C (when NP.LE.3).  --  cf. Equation (4)
  951.               DX=XD(IINT+1)-XD(IINT)
  952.               DY=YD(IINT+1)-YD(IINT)
  953.               A0=YD(IINT)
  954.               A1=YP0
  955.               YP1=YP1-YP0
  956.               YP0=YP0-DY/DX
  957.               A2=-(3.0*YP0+YP1)/DX
  958.               A3= (2.0*YP0+YP1)/(DX*DX)
  959.             ELSE
  960. C Calculates the factors for the higher-degree polynomials
  961. C (when NP.GT.3).  --  cf. Equation (20)
  962.               DX=XD(IINT+1)-XD(IINT)
  963.               DY=YD(IINT+1)-YD(IINT)
  964.               T0=YP0*DX-DY
  965.               T1=YP1*DX-DY
  966.               AA0= (T0+RENPM1*T1)/RENNM2
  967.               AA1=-(RENPM1*T0+T1)/RENNM2
  968.             END IF
  969.           END IF
  970. C End of the calculation of the coefficients of the third-degree
  971. C polynomial (when NP.LE.3) or the factors for the higher-degree
  972. C polynomials (when NP.GT.3), when the interval is not the same
  973. C as the one for the previous desired point.
  974. C Evaluates the YI value.
  975.           IF (NP0.LE.3)  THEN
  976. C - With a third-degree polynomial.  --  cf. Equation (3)
  977.             XX=XII-XD(IINT)
  978.             YI(II)=A0+XX*(A1+XX*(A2+XX*A3))
  979.           ELSE
  980. C - With a higher-degree polynomial.  --  cf. Equation (19)
  981.             U=(XII-XD(IINT))/DX
  982.             UC=1.0-U
  983.             V=AA0*((U**NP0)-U)+AA1*((UC**NP0)-UC)
  984.             YI(II)=YD(IINT)+DY*U+V
  985.           END IF
  986. C End of Subcase 3
  987.         END IF
  988.    39 CONTINUE
  989. C End of the first DO-loop
  990. C End of general case
  991.       RETURN
  992. C Special cases  --  Four data points or less
  993. C Preliminary processing for the special cases
  994.    50 X0=XD(1)
  995.       Y0=YD(1)
  996.       X1=XD(2)-X0
  997.       Y1=YD(2)-Y0
  998.       IF (ND.EQ.2)   GO TO 60
  999.       X2=XD(3)-X0
  1000.       Y2=YD(3)-Y0
  1001.       IF (ND.EQ.3)   GO TO 70
  1002.       X3=XD(4)-X0
  1003.       Y3=YD(4)-Y0
  1004.       GO TO 80
  1005. C Special Case 1  --  Two data points
  1006. C (Linear interpolation and extrapolation)
  1007.    60 A1=Y1/X1
  1008.       DO 61  II=1,NI
  1009.         YI(II)=Y0+A1*(XI(II)-X0)
  1010.    61 CONTINUE
  1011. C End of Special Case 1
  1012.       RETURN
  1013. C Special Case 2  --  Three data points
  1014. C (Quadratic interpolation and linear extrapolation)
  1015.    70 DLT=X1*X2*(X2-X1)
  1016.       A1=(X2*X2*Y1-X1*X1*Y2)/DLT
  1017.       A2=(X1*Y2-X2*Y1)/DLT
  1018.       A12=2.0*A2*X2+A1
  1019.       DO 71  II=1,NI
  1020.         XX=XI(II)-X0
  1021.         IF (XX.LE.0.0)  THEN
  1022.           YI(II)=Y0+A1*XX
  1023.         ELSE IF (XX.LT.X2) THEN
  1024.           YI(II)=Y0+XX*(A1+XX*A2)
  1025.         ELSE
  1026.           YI(II)=Y0+Y2+A12*(XX-X2)
  1027.         END IF
  1028.    71 CONTINUE
  1029. C End of Special Case 2
  1030.       RETURN
  1031. C Special Case 3  --  Four data points
  1032. C (Cubic interpolation and linear extrapolation)
  1033.    80 DLT=X1*X2*X3*(X2-X1)*(X3-X2)*(X3-X1)
  1034.       A1=(((X2*X3)**2)*(X3-X2)*Y1
  1035.      1   +((X3*X1)**2)*(X1-X3)*Y2
  1036.      2   +((X1*X2)**2)*(X2-X1)*Y3)/DLT
  1037.       A2=(X2*X3*(X2*X2-X3*X3)*Y1
  1038.      1   +X3*X1*(X3*X3-X1*X1)*Y2
  1039.      2   +X1*X2*(X1*X1-X2*X2)*Y3)/DLT
  1040.       A3=(X2*X3*(X3-X2)*Y1
  1041.      1   +X3*X1*(X1-X3)*Y2
  1042.      2   +X1*X2*(X2-X1)*Y3)/DLT
  1043.       A13=(3.0*A3*X3+2.0*A2)*X3+A1
  1044.       DO 81  II=1,NI
  1045.         XX=XI(II)-X0
  1046.         IF (XX.LE.0.0)  THEN
  1047.           YI(II)=Y0+A1*XX
  1048.         ELSE IF (XX.LT.X3) THEN
  1049.           YI(II)=Y0+XX*(A1+XX*(A2+XX*A3))
  1050.         ELSE
  1051.           YI(II)=Y0+Y3+A13*(XX-X3)
  1052.         END IF
  1053.    81 CONTINUE
  1054. C End of Special Case 3
  1055.       RETURN
  1056. C Error exit
  1057.    90 WRITE (*,99090) ND
  1058.       GO TO 99
  1059.    91 WRITE (*,99091) NI
  1060.       GO TO 99
  1061.    92 WRITE (*,99092) ID,XD(ID-1),XD(ID)
  1062.    99 WRITE (*,99099)
  1063.       RETURN
  1064. C Format statements for error messages
  1065. 99090 FORMAT (1X/ ' ***   Insufficient data points.'
  1066.      1  7X,'ND =',I3)
  1067. 99091 FORMAT (1X/ ' ***   No desired points.'
  1068.      1  7X,'NI =',I3)
  1069. 99092 FORMAT (1X/ ' ***   Two data points identical or out of ',
  1070.      1  'sequence.'/
  1071.      2  7X,'ID, XD(ID-1), XD(ID) =',I5,2F10.3)
  1072. 99099 FORMAT (' Error detected in the UVIP3P subroutine'/)
  1073.       END
  1074.